package com.zbkj.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.zbkj.common.constants.SmsConstants;
import com.zbkj.common.model.sms.SmsRecord;
import com.zbkj.common.utils.DateUtil;
import com.zbkj.common.utils.RedisUtil;
import com.zbkj.service.service.SmsRecordService;
import com.zbkj.service.service.SystemConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;

//@Slf4j
//@Service
public class AliSmsServiceImpl {

    @Autowired
    private SmsRecordService smsRecordService;

    private static final Logger logger = LoggerFactory.getLogger(AliSmsServiceImpl.class);
    @Autowired
    private SystemConfigService systemConfigService;
    @Value("${aliyun.id}")
    private String smsId;
    @Value("${aliyun.secret}")
    private String smsSecret;

    private Client client;
    @Autowired
    private RedisUtil redisUtil;


    @PostConstruct
    public void init() throws Exception {
        Config config = new Config().setAccessKeyId(smsId)
                .setAccessKeySecret(smsSecret);
        config.endpoint = "dysmsapi.aliyuncs.com";
        client = new Client(config);
    }

    public boolean pushSmsRedis(String templateCode, Map<String, Object> params, String phone) {
        if (StringUtils.isBlank(phone)) {
            return false;
        }
        HashMap<String, Object> smsParams = new HashMap<>();
        smsParams.put("templateCode", templateCode);
        smsParams.put("params", JSONObject.toJSONString(params));
        smsParams.put("phone", phone);
        redisUtil.lPush(SmsConstants.SMS_SEND_KEY, JSONObject.toJSONString(smsParams));
        return true;
    }





    /**
     * 短信队列消费者
     */
    @Async
    @Transactional
    public void consumeRedisSms() {
        Long size = redisUtil.getListSize(SmsConstants.SMS_SEND_KEY);
        logger.info("SmsServiceImpl.consume | size:" + size);
        if (size > 0) {
            for (int i = 0; i < size; i++) {
                //如果10秒钟拿不到一个数据，那么退出循环
                Object data = redisUtil.getRightPop(SmsConstants.SMS_SEND_KEY, 10L);
                if (null == data) {
                    continue;
                }
                try {
                    JSONObject jsonObject = JSONObject.parseObject(data.toString());
                    boolean result = sendSms(jsonObject.getString("templateCode"), (Map) JSONObject.parse(jsonObject.getString("params")), jsonObject.getString("phone"));
                    logger.error("发送短信失败,data = " + data);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    logger.error("发送短信失败,data = " + data);
                }
            }
        }
    }

    /**
     * 发送短信
     *
     * @param templateCode 短信发送模版的id
     * @param params       短信模版所需要的参数
     */
    public boolean sendSms(String templateCode, Map<String, Object> params, String phone) {
        SendSmsRequest smsRequest = new SendSmsRequest();
        smsRequest.setTemplateCode(templateCode);
        smsRequest.setTemplateParam(new JSONObject(params).toJSONString());
        smsRequest.setSignName("微享汇");
        smsRequest.setPhoneNumbers(phone);
        try {
            SendSmsResponse smsResponse = client.sendSms(smsRequest);
            SmsRecord smsRecord = new SmsRecord();
            smsRecord.setPhone(phone);
            smsRecord.setCreateTime(DateUtil.nowDateTime());
            smsRecord.setContent(new JSONObject(params).toJSONString());
            smsRecord.setTemplate(templateCode);
            SendSmsResponseBody responseBody = smsResponse.getBody();
            logger.info("短信发送结果：" + responseBody.getMessage() + responseBody.getCode() + responseBody.getBizId() + responseBody.getRequestId());
            if (responseBody.getCode().equals(AliSmsConstants.SMS_SEND_SUCCESS_CODE)) {
                smsRecord.setResultcode(AliSmsConstants.SMS_SEND_SUCCESS_CODE_INT);
            } else {
                smsRecord.setResultcode(AliSmsConstants.SMS_SEND_FAIL_CODE_INT);
                smsRecordService.save(smsRecord);
                return false;
            }
            smsRecord.setMemo(JSON.toJSONString(responseBody));
            // 将验证码存入redis
            smsRecordService.save(smsRecord);

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.error("发送短信失败：" + e.getMessage());
            return false;
        }
        return true;
    }

}
